#include "thread.h"

#include <sys/syscall.h>  // 系统调用相关头文件
#include <iostream>      // 标准输入输出
#include <unistd.h>      // POSIX标准头文件

namespace sylar {

// 线程局部存储变量，用于保存当前线程信息
// t_thread: 指向当前线程对象的指针
// t_thread_name: 当前线程的名称
static thread_local Thread* t_thread          = nullptr;
static thread_local std::string t_thread_name = "UNKNOWN";

// 获取当前线程的系统级ID
// 使用syscall直接调用SYS_gettid获取线程真实ID
pid_t Thread::GetThreadId()
{
	return syscall(SYS_gettid);
}

// 获取当前线程对象指针
// 返回线程局部存储中的当前线程对象
Thread* Thread::GetThis()
{
    return t_thread;
}

// 获取当前线程名称
// 返回线程局部存储中的线程名称
const std::string& Thread::GetName() 
{
    return t_thread_name;
}

// 设置当前线程名称
// 如果当前线程对象存在，则同时更新对象中的名称
// 总是更新线程局部存储中的名称
void Thread::SetName(const std::string &name) 
{
    if (t_thread) 
    {
        t_thread->m_name = name;
    }
    t_thread_name = name;
}

// 线程构造函数
// cb: 线程执行的回调函数
// name: 线程名称
Thread::Thread(std::function<void()> cb, const std::string &name): 
m_cb(cb), m_name(name) 
{
    // 创建POSIX线程
    int rt = pthread_create(&m_thread, nullptr, &Thread::run, this);
    if (rt) 
    {
        std::cerr << "pthread_create thread fail, rt=" << rt << " name=" << name;
        throw std::logic_error("pthread_create error");
    }
    // 使用信号量等待线程函数完成初始化
    m_semaphore.wait();
}

// 线程析构函数
// 如果线程存在，则将其设置为分离状态
Thread::~Thread() 
{
    if (m_thread) 
    {
        pthread_detach(m_thread);
        m_thread = 0;
    }
}

// 等待线程结束
// 如果线程存在，则调用pthread_join等待线程结束
void Thread::join() 
{
    if (m_thread) 
    {
        int rt = pthread_join(m_thread, nullptr);
        if (rt) 
        {
            std::cerr << "pthread_join failed, rt = " << rt << ", name = " << m_name << std::endl;
            throw std::logic_error("pthread_join error");
        }
        m_thread = 0;
    }
}

// 线程实际执行的函数
// arg: 传入的线程对象指针
void* Thread::run(void* arg) 
{
    Thread* thread = (Thread*)arg;

    // 设置线程局部存储
    t_thread       = thread;
    t_thread_name  = thread->m_name;
    thread->m_id   = GetThreadId();
    // 设置线程名称(最多15个字符)
    pthread_setname_np(pthread_self(), thread->m_name.substr(0, 15).c_str());

    // 获取并交换回调函数
    std::function<void()> cb;
    cb.swap(thread->m_cb); // 使用swap减少智能指针的引用计数
    
    // 通知构造函数线程初始化完成
    thread->m_semaphore.signal();

    // 执行回调函数
    cb();
    return 0;
}

}

